/**
 * 622. 设计循环队列
 * https://leetcode-cn.com/problems/design-circular-queue/
 */
public class Solutions_622 {
    public static void main(String[] args) {
        MyCircularQueue circularQueue = new MyCircularQueue(7);
        boolean res1 = circularQueue.enQueue(0);  // output: true
        System.out.println(res1);
        int res2 = circularQueue.Front();  // output: 0
        System.out.println(res2);
        boolean res3 = circularQueue.enQueue(4);  // output: true
        System.out.println(res3);
        int res4 = circularQueue.Rear();  // output: 4
        System.out.println(res4);
        boolean res5 = circularQueue.enQueue(6);  // output: true
        System.out.println(res5);
        boolean res6 = circularQueue.enQueue(3);  // output: true
        System.out.println(res6);
        int res7 = circularQueue.Rear();  // output: 3
        System.out.println(res7);
        boolean res8 = circularQueue.deQueue();  // output: true
        System.out.println(res8);
        int res9 = circularQueue.Front();  // output: 4
        System.out.println(res9);
        boolean res10 = circularQueue.deQueue();  // output: true
        System.out.println(res10);
        int res11 = circularQueue.Front();  // output: 6
        System.out.println(res11);
    }
}

/**
 * 循环队列效果：
 * 设置队列大小 5：{#, #, #, #, #}
 * [1, 2, 3, 4, 5] 5 个元素入队后，队列：{1, 2, 3, 4, 5}，此时队首元素为 1，队尾元素为 5
 * 2 个元素出队（先进先出，队首元素出队）后，队列：{ ,  , 3, 4, 5}，此时队首元素为 3，队尾元素为 5
 * [6] 1 个元素入队后，队列：{6,  , 3, 4, 5}，此时队首元素为 3，队尾元素为 6
 * 队列没有元素时，不能做出队及获取队首，队尾元素
 * 队列已满时，不能做元素入队操作
 */
class MyCircularQueue {
    int[] arr;
    // 队首索引，用于取出队首元素
    int head;
    // 队尾索引，用于元素入队及取出队尾元素
    int tail;
    // 队列元素个数
    int size;

    /** Initialize your data structure here. Set the size of the queue to be k. */
    public MyCircularQueue(int k) {
        arr = new int[k];
        head = 0;
        tail = -1;
        size = 0;
    }

    /** Insert an element into the circular queue. Return true if the operation is successful. */
    public boolean enQueue(int value) {
        if (isFull()) {
            return false;
        }
        // 队列未满时，队尾添加元素
        ++tail;
        if (tail == arr.length) {
            tail = 0;
        }
        arr[tail] = value;
        size ++;
        return true;
    }

    /** Delete an element from the circular queue. Return true if the operation is successful. */
    public boolean deQueue() {
        if (isEmpty()) {
            return false;
        }
        // 队列不为空时，弹出队首元素
        size --;
        head ++;
        if (head == arr.length) {
            head = 0;
        }
        return true;
    }

    /** Get the front item from the queue. */
    public int Front() {
        if (isEmpty()) {
            return -1;
        }
        // 返回队首元素
        return arr[head];
    }

    /** Get the last item from the queue. */
    public int Rear() {
        if (isEmpty()) {
            return -1;
        }
        // 返回队尾元素
        return arr[tail];
    }

    /** Checks whether the circular queue is empty or not. */
    public boolean isEmpty() {
        return size == 0;
    }

    /** Checks whether the circular queue is full or not. */
    public boolean isFull() {
        return size == arr.length;
    }
}
